/*
 * DprLockManager.cpp
 *
 *  Created on: 2012-11-26
 *      Author: kylin
 */

#include <QMutexLocker>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "DprLockManager.h"
#include <gdata.h>

//////////////////////////////////////////////////////////////////////
// class DprSwitch

#define SWITCH_OPEN		0
#define SWITCH_CLOSE	1

DprSwitch::DprSwitch(const QString &devNode)
 : m_devNode(devNode)
{
	m_fd=-1;
}

DprSwitch::~DprSwitch()
{

}

bool DprSwitch::init()
{
	m_fd=::open(m_devNode.toAscii().data(),O_RDWR);
	if(m_fd==-1)
		return false;

	return true;
}

void DprSwitch::clear()
{
	if(m_fd!=-1)
	{
		::close(m_fd);
		m_fd=-1;
	}
}

bool DprSwitch::opening(int switchNum)
{
	if(m_fd==-1)
		return false;

	::ioctl(m_fd,SWITCH_OPEN,&switchNum);
	return true;
}

bool DprSwitch::closing(int switchNum)
{
	if(m_fd==-1)
		return false;

	::ioctl(m_fd,SWITCH_CLOSE,&switchNum);
	return true;
}

//////////////////////////////////////////////////////////////////////
// class DprLock
DprLock::DprLock(int addr)
 : m_addr(addr)
{
	m_wiringLock=true;
	m_mainLock=true;
	m_linkLock=true;
}

DprLock::~DprLock()
{

}

void DprLock::updateLockWiring(bool state)
{

}

void DprLock::updateLockMain(bool state)
{

}

void DprLock::updateLockLink(bool state)
{

}

//////////////////////////////////////////////////////////////////////
// class DprLockManager
DprLockManager::DprLockManager(const QString &switchDevNode)
 : m_switchDevNode(switchDevNode)
{
	m_switch=new DprSwitch(m_switchDevNode);
}

DprLockManager::~DprLockManager()
{
	qDeleteAll(m_locks);
	m_locks.clear();

	delete m_switch;

	qDeleteAll(m_lstSoe);
	qDeleteAll(m_lstAlarm);
}

void DprLockManager::setRunningState(RunningState rs)
{
	QMutexLocker locker(&m_mutex);
	m_rs=rs;
}

bool DprLockManager::init()
{
	int index;
	DprLock* lock;
	QMutexLocker locker(&m_mutex);
	if(!m_switch->init())
		return false;

	for(int i=0;i<gLockEntries.size();i++)
	{
		index=i;
		lock=new DprLock(index);

		m_locks.append(lock);

		connect(lock,SIGNAL(sigPowerDown(int)),this,SLOT(powerDown(int)));

		m_wiringLockAddrMap.insert(gLockEntries[i].addrWiring,index);
		m_mainLockAddrMap.insert(gLockEntries[i].addrMain,index);
		m_linkLockAddrMap.insert(gLockEntries[i].addrLink,index);

		m_lockSwitchMap.insert(index,gLockEntries[i].switchNum);
	}

	return true;
}

void DprLockManager::clear()
{
	QMutexLocker locker(&m_mutex);

	qDeleteAll(m_locks);
	m_locks.clear();

	delete m_switch;

	m_wiringLockAddrMap.clear();
	m_mainLockAddrMap.clear();
	m_linkLockAddrMap.clear();

	m_lockSwitchMap.clear();

	m_switch->clear();

	qDeleteAll(m_lstSoe);
	m_lstSoe.clear();

	qDeleteAll(m_lstAlarm);
	m_lstAlarm.clear();
}

bool DprLockManager::lockState(unsigned short lockAddr,bool &state)
{
	DprLockType lockType;
	int index=lockIndex(lockAddr,lockType);

	if(index<0)
		return false;

	if(index>=m_locks.size())
		return false;

	switch(lockType)
	{
		case dltWiring:
			state = m_locks.at(index)->lockWiring();
			break;

		case dltMain:
			state = m_locks.at(index)->lockMain();
			break;

		case dltLink:
			state = m_locks.at(index)->lockLink();
			break;

		default:
			return false;
	}

	return true;
}

bool DprLockManager::updateLockState(unsigned short lockAddr,bool state)
{
	DprLockType lockType;
	int index=lockIndex(lockAddr,lockType);

	if(index<0)
		return false;

	if(index>=m_locks.size())
		return false;

	bool bret=true;

	switch(lockType)
	{
		case dltWiring:
			m_locks.at(index)->updateLockWiring(state);
			break;

		case dltMain:
			m_locks.at(index)->updateLockMain(state);
			break;

		case dltLink:
			m_locks.at(index)->updateLockLink(state);
			break;

		default:
			bret = false;
			break;
	}

	return bret;
}

bool DprLockManager::soeEvent(int index,DprSoeEvent &event)
{
	if((index<0)||(index>=m_lstSoe.size()))
		return false;

	DprSoeEvent* eventTmp=m_lstSoe.at(index);
	event.lockAddr=eventTmp->lockAddr;
	event.lockIndex=eventTmp->lockIndex;
	event.switchNum=eventTmp->switchNum;
	event.switchState=eventTmp->switchState;
	event.time=eventTmp->time;
	event.mSecond=eventTmp->mSecond;
	return true;
}

bool DprLockManager::alarmEvent(int index,DprAlarmEvent &event)
{
	if((index<0)||(index>=m_lstAlarm.size()))
		return false;

	DprAlarmEvent* eventTmp=m_lstAlarm.at(index);
	event.alarmCode=eventTmp->alarmCode;
	event.time=eventTmp->time;
	event.mSecond=eventTmp->mSecond;
	return true;
}

void DprLockManager::testOutput(int switchNum)
{
	QMutexLocker locker(&m_mutex);

	if(m_rs==rsRun)
		return;

	m_switch->opening(switchNum);
}

void DprLockManager::powerDown(int index)
{
	QMutexLocker locker(&m_mutex);

	if(m_rs==rsMaintain)
		return;

	if(m_lockSwitchMap.contains(index))
	{
		m_switch->opening(m_lockSwitchMap.value(index));
	}
}

int DprLockManager::lockIndex(unsigned short lockAddr,
		DprLockType &type)
{
	QMutexLocker locker(&m_mutex);

	if(m_wiringLockAddrMap.contains(lockAddr))
	{
		type=dltWiring;
		return m_wiringLockAddrMap.value(lockAddr);
	}

	if(m_mainLockAddrMap.contains(lockAddr))
	{
		type=dltMain;
		return m_mainLockAddrMap.value(lockAddr);
	}

	if(m_linkLockAddrMap.contains(lockAddr))
	{
		type=dltLink;
		return m_linkLockAddrMap.value(lockAddr);
	}

	return -1;
}


